package yl.hs.bmipfull.service.production.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import yl.hs.bmipfull.daos.laboratory.*;
import yl.hs.bmipfull.daos.material.IInputMaterialRecordDao;
import yl.hs.bmipfull.daos.material.IOutboundCollectingRecordDao;
import yl.hs.bmipfull.daos.production.IFinishProductWarehouseRecordDao;
import yl.hs.bmipfull.daos.production.IProductionInspectionRecordDao;
import yl.hs.bmipfull.daos.production.IProductionPackageDao;
import yl.hs.bmipfull.daos.production.IProductionTaskFertilizerDao;
import yl.hs.bmipfull.daos.salemanage.ISaleOrderDao;
import yl.hs.bmipfull.daos.salemanage.ISaleOrderProductDetailDao;
import yl.hs.bmipfull.pojo.laboratory.TaskConfigDetailsEntity;
import yl.hs.bmipfull.pojo.production.ProductionTaskFertilizerEntity;
import yl.hs.bmipfull.pojo.salemanage.SaleOrderEntity;
import yl.hs.bmipfull.pojo.salemanage.SaleOrderProductDetailEntity;
import yl.hs.bmipfull.service.production.IProductionTaskFertilizerService;
import yl.hs.bmipfull.utils.DataState;
import yl.hs.bmipfull.utils.Tl;
import yl.hs.bmipfull.utils.datastate.ActionType;
import yl.hs.bmipfull.viewmodels.PageQuery;
import yl.hs.bmipfull.viewmodels.PageResult;
import yl.hs.bmipfull.viewmodels.production.TransferList;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 作用:  服务层接口实现<br/>
 * 创建时间: 2023年06月07日 15时26分04秒 <br/>
 *
 * @author 吴高丰
 */
@Service
public class ProductionTaskFertilizerServiceImpl extends ProductionBaseService implements IProductionTaskFertilizerService {

    @Autowired
    IProductionTaskFertilizerDao dao;
    @Autowired
    ISaleOrderProductDetailDao detailDao;
    @Autowired
    ISaleOrderDao orderDao;
    @Autowired
    IProductConfigDao configDao;
    @Autowired
    ITaskConfigDao TaskconfigDao;
    @Autowired
    ITaskConfigDetailsDao detailsDao;
    @Autowired
    IInputMaterialRecordDao inputMaterialRecordDao;
    @Autowired
    IOutboundCollectingRecordDao outboundCollectingRecordDao;
    @Autowired
    IFinishProductWarehouseRecordDao finishProductWarehouseRecordDao;
    @Autowired
    IPackageInfoDao packageInfoDao;
    @Autowired
    IProductInfoDao productInfoDao;
    @Autowired
    IProductCateDao cateDao;
    @Autowired
    IProductionPackageDao productionPackageDao;
    @Autowired
    IProductionInspectionRecordDao inspectionRecordDao;

    @Override
    public List<ProductionTaskFertilizerEntity> queryList(PageQuery pageQuery) throws Exception {
        pageQuery.checkSortSides(ProductionTaskFertilizerEntity.class);
        return dao.queryPage(pageQuery.getQuery());
    }

    @Override
    public PageResult<Object> queryPage(PageQuery pageQuery, int rowNum, int page) throws Exception {
        pageQuery.checkSortSides(ProductionTaskFertilizerEntity.class);
        pageQuery.getQuery().put("querySkip", (page - 1) * rowNum);
        pageQuery.getQuery().put("pageSize", rowNum);
        PageResult<Object> result = new PageResult(rowNum);
        result.setRecords(dao.queryCountByCondition(pageQuery.getQuery()));
        result.setPage(page);
        var ss = dao.queryPage(pageQuery.getQuery());
        List<Object> list = new ArrayList<>();
        for (ProductionTaskFertilizerEntity s : ss) {
            var entitymap = s.toMap();
            var query = new BigDecimal(0);
            var entity = finishProductWarehouseRecordDao.queryByTaskSNAfter(s.getSn(), 0);
            if (entity.size() > 0) {
                query = entity.stream().map(t -> t.getWeight()).reduce(BigDecimal::add).get();
            }
            entitymap.put("scquantity", query);
            entitymap.put("syquantity", s.getQuantity().subtract(query).setScale(2, RoundingMode.DOWN));
            entitymap.put("FinishProductWarehouse", entity);
            list.add(entitymap);
        }
        result.setData(list);
        return result;
    }


    @Override
    public ProductionTaskFertilizerEntity findBySn(String sn) {
        return dao.findBySN(sn);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer saveproduction_task_fertilizer(Map<String, Object> model, String sn) throws Exception {
        Integer result = 0;
        ProductionTaskFertilizerEntity entity = null;
        if (Tl.isEmpty(sn)) {
            //执行保存
            entity = new ProductionTaskFertilizerEntity();
            Tl.getChangeLog(entity, model);
            entity.setPYFieldValue();
            entity.setSn(queryNewSN(ProductionTaskFertilizerEntity.class));
            var pack = productionPackageDao.queryByProductSNAndPackSN(entity.getProductSN(), entity.getPackageSN());
            if (pack != null) {
                entity.setPackImage(pack.getImage());
            }
            result = dao.insertNew(entity);
            if (result > 0) {
                writeLog(ActionType.CREATE, entity.getSn(), "插入信息", Tl.toJson(entity), ProductionTaskFertilizerEntity.class);
            }

        } else {
            //执行修改
            entity = findBySn(sn);
            Tl.getChangeLog(entity, model);
            entity.setPYFieldValue();
            var pack = productionPackageDao.queryByProductSNAndPackSN(entity.getProductSN(), entity.getPackageSN());
            if (pack != null) {
                entity.setPackImage(pack.getImage());
            }
            result = dao.update(entity);
            if (result > 0) {
                writeLog(ActionType.UPDATE, sn, "更新信息", Tl.toJson(entity), ProductionTaskFertilizerEntity.class);
            }
        }

        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer delete(String sn) {
        var sns = sn.split(",");
        Integer result = dao.changeStateBySN(sns, DataState.DELETED.code);
        if (result > 0) {
            var task = dao.findBySN(sn);
            if (task.getSaleOrderSn() != null) {
                var snlist = task.getSaleOrderSn().replace("[", "").replace("]", "").replace(" ", "").split(",");
                for (String s : snlist) {
                    var data = orderDao.findBySN(s);
                    if (data != null) {
                        data.setState((short) -1);
                        orderDao.update(data);
                    }
                }
            }
            writeLog(ActionType.DELETE, sns, ProductionTaskFertilizerEntity.class);
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer saveTaskBySaleOrder(List<String> data) {
        try {
            List<SaleOrderProductDetailEntity> entity = new ArrayList<>();
            List<SaleOrderEntity> orderentity = new ArrayList<>();
            var datas = orderDao.queryByList(data);
            for (SaleOrderEntity item : datas) {
                if (item.getState() > 2) {
                    return -1;
                }
                orderentity.add(item);
                var detail = detailDao.queryBySaleOrderSn(item.getSn());
                entity.addAll(detail);
                item.setState((short) 3);
                detailDao.updateBySn(detail.stream().map(t -> t.getSn()).collect(Collectors.toList()), (short) 3);
                orderDao.update(item);
            }
            var dd = entity.stream().collect(Collectors.groupingBy(SaleOrderProductDetailEntity::getPbSn,
                    Collectors.groupingBy(SaleOrderProductDetailEntity::getProductSN,
                            Collectors.groupingBy(SaleOrderProductDetailEntity::getPackageSn,
                                    Collectors.toList()))));
            for (var product : entity) {
                var ss = orderDao.findBySN(product.getSaleSn());
                ProductionTaskFertilizerEntity result = new ProductionTaskFertilizerEntity();
                var config = configDao.findBySN(product.getPbSn());
                var quantity = product.getQuantity();
                result.setSn(queryNewSN(ProductionTaskFertilizerEntity.class));
                result.setSaleOrderSn(ss.getSn());
                result.setSaleOrdeDetail(product.getSn());
                result.setPbName(config.getConfigName());
                result.setPbSn(config.getSn());
                result.setAddTime(new Date());
                result.setQuantity(quantity);
                result.setState((short) 2);
                result.setPbstate((short) 0);
                result.setCustomerName(ss.getCustomerName());
                result.setCustomerSN(ss.getCustomerSN());
                result.setContractSN(ss.getContractSN());
                var packinfo = packageInfoDao.findBySN(product.getPackageSn());
                if (packinfo != null) {
                    result.setPackageName(packinfo.getPackName());
                    result.setPackageSN(packinfo.getSn());
                    result.setPackageWeight(packinfo.getPackWeight());
                    result.setPackUnit(packinfo.getPackUnit());
                    result.setPackWay(packinfo.getPackWay());
                }
                var productinfo = productInfoDao.findBySN(product.getProductSN());
                if (productinfo != null) {
                    result.setProductCateSN(productinfo.getProductCateSN());
                    result.setProductName(productinfo.getProductName());
                    result.setProductSpec(productinfo.getProductSpec());
                    result.setProductSN(productinfo.getSn());
                    var cate = cateDao.findBySN(productinfo.getProductCateSN());
                    if (cate != null) {
                        result.setProductCateName(cate.getCateName());
                    }
                    var productpage = productionPackageDao.queryByProductSNAndPackSN(result.getProductSN(), result.getPackageSN());
                    if (productpage != null) {
                        result.setPackImage(productpage.getImage());
                    }
                }
                dao.insertNew(result);
            }
            return 1;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    @Override
    public Integer updateTask(String sn, short state) {
        return dao.updateTask(sn, state);
    }

    @Override
    public List<Object> queryOrderDetail(List<String> snlist) {
        var result = detailDao.queryOrderDetail(snlist);
        List<Object> results = new ArrayList<>();
        for (SaleOrderProductDetailEntity item : result) {
            var saleorder = orderDao.findBySN(item.getSaleSn());
            var data = item.toMap();
            data.put("customerName", saleorder.getCustomerName());
            data.put("addTime", saleorder.getAddTime());
            data.put("gettruckplate", saleorder.getTruckPlate());
            results.add(data);
        }
        return results;
    }

    @Override
    public Integer changeBySNList(String sn, short state) {
        var snList = sn.split(",");
        if (state == 5) {
            if (snList.length > 0) {
                for (var taskSn : snList) {
                    var taskEntity = dao.findBySN(taskSn);
                    if (taskEntity != null && taskEntity.getSaleOrderSn() != null) {
                        var saleOrderSNList = taskEntity.getSaleOrderSn().replace("[", "").replace("]", "").replace(" ", "").split(",");
                        //销售订单转提货中状态
                        orderDao.changeToState(saleOrderSNList, (short) 5);
                        var saleOrderSNListDetail = taskEntity.getSaleOrdeDetail().replace("[", "").replace("]", "").replace(" ", "").split(",");
                        detailDao.changeToState(saleOrderSNListDetail, (short) 5);
                        for (String s : saleOrderSNListDetail) {
                            var saledetail = detailDao.findBySN(s);
                            try {
                                var sale = orderDao.findBySN(saledetail.getSaleSn());
                                sendMsg(sale.getSaleUserSN(), "订单生产完成提醒", sale.getCustomerName() + "客户的" + saledetail.getProductName() + "产品" + saledetail.getQuantity() + "已生产完成");
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }
        }
        return dao.changeStateBySN(snList, state);
    }

    @Override
    public List<ProductionTaskFertilizerEntity> findBySNList(String snList) {
        return dao.findBySNList(snList.split(","));
    }

    @Override
    public Map<String, Object> GetRmQueary(String taskSn) {
        var taskk = dao.findBySN(taskSn);
        var task = TaskconfigDao.queryConfigByTaskSN(taskSn);
        Map<String, Object> results = new HashMap<>();
        List<Object> result = new ArrayList<>();
        if (task.size() > 0) {
            var taskentity = task.get(0);
            var ss = detailsDao.queryByTaskConfigSn(taskentity.getSn());
            for (TaskConfigDetailsEntity s : ss) {
                var entity = s.toMap();
                entity.put("number", s.getProduction().multiply(taskk.getQuantity()));
                result.add(entity);
            }
        }
        results.put("pb", result);
        var input = inputMaterialRecordDao.queryByTaskSn(taskSn);
        var out = outboundCollectingRecordDao.queryByTaskSn(taskSn);
        results.put("ly", out);
        results.put("tl", input);
        return results;
    }

    @Override
    public Integer transferProduction(TransferList model) {
        model.getModel().forEach(s -> {
            var task = dao.findBySN(s.getTaskSN());
            if (s.getState() == 1) {
                task.setState((short) 3);
                task.setAddTime(s.getDate());
                dao.update(task);
            } else {
                updateTask(task, s.getQuantity());
                task.setQuantity(s.getQuantity());
                task.setSn(queryNewSN(ProductionTaskFertilizerEntity.class));
                task.setState((short) 3);
                task.setAddTime(s.getDate());
                dao.insertNew(task);
            }
        });
        return 1;
    }

    public Integer updateTask(ProductionTaskFertilizerEntity entiy, BigDecimal query) {
        entiy.setQuantity(entiy.getQuantity().subtract(query));
        return dao.update(entiy);
    }

    @Override
    public List<ProductionTaskFertilizerEntity> queryByContractSN(String contractSN, Date time, String productSN) {
        return dao.queryByContractSN(contractSN, time, productSN);
    }
}